/**************定义常量 需要重新写 *************/

var cdrawcnt = 0;
//node 的宽度
var nwidth = 100;
//node 的高度
var nheight = 150;
//X坐标间距系数  X Spacing factor
var xsf = 0.5;
//Y坐标间距系数 Y Spacing factor
var ysf = 0.3;
//是否显示 顶级
var treeDrag = true;
var nodeNumber = 0;
var canvasScaleOp = 1, resetPosCnt = 0, resetlinkCnt = 0, spouseJoinCnt = 0, linking = 0;
var currentScale = 1.0;
var posMoveX = 0, posMoveY = 0;
var canvarDrag;
var zoomDisplay, currentScale;
var oBox;

var drawed = {};
var spouseList = {}, nodePositions = {};
//画板,
var canvas, drawline;
//联系的间距
var lineSplit = 5;
//底部的 链接线
var bottomMargin = -5;
var drawMoveX = 0, drawMoveY = 0;
var jpMinX = 0, jpMinY = 0, jpMaxX = 0, jpMaxY = 0;
/**************  end 定义常量 *************/
///全部数据重新写
function allReset() {
    treeDrag = true;
    nodeNumber = 0;
    canvasScaleOp = 1, resetPosCnt = 0, resetlinkCnt = 0, spouseJoinCnt = 0, linking = 0;
    currentScale = 1.0;
    drawMoveX = 0, drawMoveY = 0, cdrawcnt = 0;
    jpMinX = 100000, jpMinY = 10000, jpMaxX = -10000, jpMaxY = -10000;
}


/**************  end 定义常量 *************/
//自定义谈话框
var jpAlter = function (message) {
    alert(message);
}


var moved = {};
//添加家庭
var addFamliy = function (n) {
    var id = n.id;
    var family = new familyNode();
    families[id] = family;
    if (n.sex == "1") {
        family.sethusband(n);
        for (var j = 0; j < n.spouse.length; j++) {
            var s = n.spouse[j];
            family.addWife(s);
            families[s.id] = family;
        }
    }
    else {
        family.addWife(n);
        for (var j = 0; j < n.spouse.length; j++) {
            var s = n.spouse[j];
            family.sethusband(s);
            families[s.id] = family;
        }
    }
    var mid = family.mainid();
    if (n.sex == "1" || !onlyFamilies[mid]) {
        onlyFamilies[mid] = family;
    }
    return family;
}

//校正水平位置
var correctedX = function () {
    families = {};
    onlyFamilies = {};
    geneFamilies = {};
    var geneMin = 15000, geneMax = -1100;
    for (var k = 0; k < jpnodes.length; k++) {
        var n = jpnodes[k];
        var id = n.id;

        var f = families[id];
        if (!f) {

            family = addFamliy(n);
            var gene = n.gene;
            if (geneMax < gene) { geneMax = gene; }
            if (geneMin > gene) { geneMin = gene; }
            //处理数据
            if (!geneFamilies[gene]) {
                geneFamilies[gene] = [];
            }
            geneFamilies[gene][geneFamilies[gene].length] = family;
        }
    }


    for (var gene = geneMax; gene >= geneMin; gene--) {
        var list = geneFamilies[gene];
        if (list) {
            for (var k = 0; k < list.length; k++) {
                var family = list[k];
                jiaoFamily(family);
                var left = family.leftFamily();

                if (left) {
                    console.log(family.mainid() + "  left:" + left.mainid());
                    var lmax = left.maxX();
                    var min = family.minX();
                    if (lmax + xsf * nwidth != min) {
                        var movel = (lmax + xsf * nwidth) - min;
                        moved = {};
                        family.move(movel);
                    }
                }
            }
        }
    }

    //对内缩
    for (var gene = geneMax; gene >= geneMin; gene--) {
        var list = geneFamilies[gene];
        if (list) {
            for (var k = 0; k < list.length; k++) {
                var family = list[k];
                var left = family.leftFamily();
                var max = null;
                var mainid = family.mainid();
               
                while (left) {
                    var mainLeft = left.mainid();
                    var match = $nodes[mainLeft].father == $nodes[mainid].father;
                    if (!match) {
                        var h = $nodes[mainid];
                        var s = family.wifes[0];
                        if (h && s) {
                            s = $nodes[s.id];
                            if (s) {
                                if (parseFloat(h.deep) > parseFloat(s.deep)) {
                                    if ($nodes[mainLeft].father == $nodes[s.id].father) {
                                        match = true;
                                    }
                                }
                            }
                        }
                    }

                    if (match) {
                        console.log(family.mainid() + "  left:" + left.mainid());
                        //处理压缩
                        for (var g1 = gene; g1 <= geneMax; g1++) {

                            var leftMax = left.geneMax(g1);
                            var rmin = family.geneMin(g1);
                            if (leftMax === null || rmin === null) {
                                break;
                            }
                            if (rmin - leftMax < max || max === null) {
                                max = rmin - leftMax;
                            }
                            console.log("g:" + g1 + " max:" + max + " rmin:" + rmin + " lmax:" + leftMax);
                        }
                    }
                    else {
                        break;
                    }
                    left = left.leftFamily();
                }
                if (max !== null) {
                    if (max != xsf * nwidth) {
                        var movel = xsf * nwidth - max; // (lmax + xsf * nwidth) - mi;
                        moved = {};
                        family.move(movel);
                        jiaoAncestors(family);
                    }
                }
            }
        }
    }
    var rootFamily = families[$root.id];
    if (rootFamily) {
        jiaoFamily(rootFamily);
    }
}

//校对上级
var jiaoAncestors = function (family) {
    var mainid = family.mainid();
    var fnode = $nodes[$nodes[mainid].father];
    if (fnode) {
        var fatherFamily = families[fnode.id];
        if (fatherFamily) {
            jiaoFamily(fatherFamily);
            jiaoAncestors(fatherFamily);
        }
    }
    else {
        var mnode = $nodes[$nodes[mainid].mother];
        if (mnode) {
            var aFamily = families[mnode.id];
            if (aFamily) {
                jiaoFamily(aFamily);
                jiaoAncestors(aFamily);
            }
        }
    }
}
var jiaoFamily = function (family) {
    var cMin = family.cOnlyMin();
    var cMax = family.cOnlyMax();
    if (cMin != null) {
        var center = (cMin + cMax) / 2;
        var number = family.wifes.length + (family.husband ? 1 : 0);
        if (isShiXiTu && sxSetting.spousejoin==1) {
            center -= nwidth / 2;
        }
        else {
            if (number % 2 == 1) {
                center -= 0.5 * nwidth;
                var n2 = Math.ceil(number / 2) - 1;
                center -= n2 * (1 + xsf) * nwidth;
            }
            else {
                var n2 = number / 2;
                center -= n2 * (1 + xsf * 0.5) * nwidth;
            }
        }
        var b = 0;
        if (family.husband) {
            family.husband.x = center;
            b++;
        }
        for (var j = 0; j < family.wifes.length; j++) {
            family.wifes[j].x = center + (1 + xsf) * nwidth * (b + j);
        }
    }
}

var bindContainer = function () {
    $(".container").click(function () {

        var id = $(this).attr("nodeid");
        $(this).addClass("ctr-figure-curr").siblings().removeClass("ctr-figure-curr");
        for (var j = 0; j < jpnodes.length; j++) {
            if (jpnodes[j].id == id) {
                snode = jpnodes[j];
                var g = snode.gene;
                $("[scalegene=" + (g) + "]").addClass("curr").siblings().removeClass("curr");
                break;
            }
        }
        if ($(this).hasClass('tree-node-info')) {
            addChoiceBox();
        }
    });
    //移上人物右侧弹出主页、家谱、资料、传记框
    $(".container").hover(function () {
         
        $(this).addClass("container-show");
    }, function () {
        $(this).removeClass("container-show");
    });

    //点击人物弹出左侧信息栏
    $(".content-tree-box").find(".container").live('click', function () {
        var person = $(this).attr("name"); //获取人物的name值是男或是女
        var n_image = $(this).find($(".ctr-figure-image img")).prop("src"); //获取人物头像
        var n_value = $(this).find($(".ctr-figure-name")).html(); //获取人物名称
        var male_bgcolor = $(".person-frame-male .ctr-figure-image").css("background-color"); //获取人物男性的头像背景色
        var female_bgcolor = $(".person-frame-female .ctr-figure-image").css("background-color"); //获取人物女性的头像背景色
        $("#hidden_user_sex").attr("name", person); //赋值给左侧栏的隐藏域
        $(".smbi-top .media-txt a").html(n_value);
        $(".smbi-top .media-img img").prop("src", n_image);
        $node = $nodes[snode.id];

        $(".summay_text").text(snode.summay ? snode.summay : "--");
        if ($(this).hasClass("person-frame-male")) {//如果是男性
            $(".smbi-top .media-img").css({ "background": male_bgcolor });
        }
        if ($(this).hasClass("person-frame-female")) {//如果是女性
            $(".smbi-top .media-img").css({ "background": female_bgcolor });
        }
        var node = $nodes[snode.id];
        $(".xing-text").text(node.xing ? node.xing : "--");
        $(".sex-text").text(node.sex == "1" ? "男" : "女");
        $(".brothersort-text").text(node.brothersort ? node.brothersort : "--");
        $(".truename-text").text(getJPShowName(node));
        $(".zibeitext-text").text(node.zibeitext ? node.zibeitext : "--");
        $(".ziname-text").text(node.zibeiming ? node.zibeiming : "--");
        $(".truename-text").text(node.truename ? node.truename : "--");
        $(".huiname-text").text(node.honorific ? node.honorific : getJPShowName(node));

        $(".alive-text").text(node.alive == "1" ? "是" : "否"); // .is(":checked");
        if (node.tformat == 1) {
            $('.birthstr-text').text(node.cbirthday ? node.cbirthday : "--");
        }
        else {
            $('.birthstr-text').text(node.birthstr ? node.birthstr : "--");
        }
        if (node.dietformat == 1) {
            $(".diestr-text").text(node.cdieday ? node.cdieday : "--");
        }
        else {
            $(".diestr-text").text(node.diestr ? node.diestr : "--");
        }

        $(".education-text").text(educationlevel[node.education]);
        $(".zhangdi-text").text(node.zaddress ? node.zaddress : "--");
        $(".mobile-text").text(node.mobile ? node.mobile : "--");
        $(".school-text").text(node.school ? node.school : "--");
        $(".work-text").text(node.work ? node.work : "--");

        $(".summay-text").text(node.summay ? node.summay : "--");

        $(".oldxueli-text").text(node.oldxueli ? node.oldxueli : "--");
        $(".zhicheng-text").text(node.zhicheng ? node.zhicheng : "--");
        $(".hao-text").text(node.hao ? node.hao : "--");
        $(".alive-text-0").show();
        if (node.alive == 1) {
            $(".alive-text-0").hide();
        }
    });

}


function jpdraw() {

    drawLastDiv = null;
    correctedX();
    for (var j = 0; j < jpnodes.length; j++) {
        var n = jpnodes[j];
        if (n.isDelete || !n.isShow) {//判断是否删除
            continue;
        }
        var left = n.x;
        var top = n.y;
        if (left < jpMinX) jpMinX = left;
        if (top < jpMinY) jpMinY = top;
        if (left > jpMaxX) jpMaxX = left;
        if (top > jpMaxY) jpMaxY = top;
    }
   
    for (var j = 0; j < jpnodes.length; j++) {
        var n = jpnodes[j];
        if (n.isDelete) {//判断是否删除
            continue;
        }
        if (!n.isShow) {//判断是否不显示
            continue;
        }
        div = drawNode(n);
    }
    bindContainer();
}
var drawLastDiv = null;

var addAfterSible = function (div) {
    if (div.find(".sible-btn").length > 4) {
        var list = div.find(".sible-btn");
        var _figurehtml = $('<div class="add-figure-box frame-windows">' +
			    '<div class="add-figure-box-bg"></div>' +
			    '<div class="add-figure-box-txt">' +
				    '<div class="ico-closed">&times;</div>' +
				    '<ul></ul></div></div>');
        for (var j = 3; j < list.length; j++) {
            var p = $(list[j]);
            p.remove();
            var c = $("<li class='sible-btn sible-box sible-box-boy'></li>").append(p);
            _figurehtml.find("ul").append(c); //  += "<li class='sible-btn'></li>";

        }
        div.find(".ctr-info-theme").append('<a class="  sible-btn item-more" href="javascript:;" ondragstart="return false">更多</a>');
        div.find(".item-more").click(function () {
            $("#cont-body").prepend(_figurehtml);
        });

    }
}

//画单个节点
var drawNode = function (n, beforeMove) {
    if (beforeMove) {
        $("[nodeid=" + n.id + "]").remove();
    }

    var div = $('<div class="container tree-node-info">' +
				'<div class="ctr-figure">' +
					'<a href="javascript:;" class="ctr-figure-image" ondragstart="return false"><img src=""></a>' +
					'<div class="ctr-figure-name"></div>' +
					'<div class="ctr-figure-more">+</div>' +
					'<div class="ctr-figure-more-bg"></div>' +
				'</div>' +
				'<div class="ctr-info">' +
					'<div class="ctr-info-arrow"></div>' +
					'<div class="ctr-info-theme">' +
						'<a class="item-class-index sible-btn" href="javascript:;" ondragstart="return true">主页</a>' +
    //'<a class="item-class-zupu" href="javascript:;" ondragstart="return false">家谱</a>'+
                       (n.canSort() ? '<a class="item-class-sort node-action node-sort  sible-btn" href="javascript:;" ondragstart="return false">排序</a>' : "") +
                       (n.canExtend() ? '<a class="item-class-extend node-action node-extend  sible-btn" href="javascript:;" ondragstart="return false">展开</a>' : "") +
                       (n.canIntend() ? '<a class="item-class-intend node-action node-intend  sible-btn" href="javascript:;" ondragstart="return false">收缩</a>' : "") +
                       (n.canDelete() ? '<a class="item-class-delete node-action node-delete  sible-btn" href="javascript:;" ondragstart="return false">删除</a>' : "") +
                       '<a class="item-class-record  sible-btn" href="javascript:;" ondragstart="return false">记录</a>' +
                       '<a class="item-class-family  sible-btn" href="javascript:;" ondragstart="return false">家庭</a>' +
                       '<a class="item-class-fangxi  sible-btn" href="javascript:;" ondragstart="return false">房系</a>' +
                       '<a class="item-class-mother  sible-btn" href="javascript:;" ondragstart="return false">编辑母亲</a>' +
					'</div>' +
				'</div>' +
			'</div>');
    addAfterSible(div);

    var e_nan = "person-frame-male";
    var e_nv = "person-frame-female";
    var avatar = n.avatar;
    if (drawLastDiv) {
        drawLastDiv.after(div);
    }
    else {
        $container.html(div);
    }
    nodesById[n.id] = n;
    div.css("left", n.x);
    div.css("top", n.y);
    div.attr("left", n.x);
    div.attr("top", n.y);
    div.find(".ctr-figure-name").text(getJPShowName($nodes[n.id]));
    div.attr("nodeid", n.id);
    div.attr("wzchar", n.wzchar);
    div.attr("gene", n.gene);
    div.attr("sort", n.sort);
    div.attr("left", n.left ? (n.left.wzchar + " s:" + n.left.sort) : "");
    div.attr("right", n.right ? (n.right.wzchar + " s:" + n.right.sort) : "");
    div.attr("leftid", n.left ? n.left.id : "");
    div.attr("rightid", n.right ? n.right.id : "");
    div.attr('soncnt', n.son.length);
    div.attr('childrencnt', n.childrens.length);
    div.attr('spousecnt', n.spouse.lenght);
    if (n.sex == 1) {
        div.addClass(e_nan);
        div.attr("name", e_nan);
    }
    else {
        div.addClass(e_nv);
        div.attr("name", e_nv);
    }
    div.find(".ctr-figure-image > img").attr("src", avatar);
    drawLastDiv = div;
    return div;
}


//操作的时候处理节点信息
var treeAddNode = function (importNode, newNode, position) {
    var family = families[importNode.id];
    moved = {};
    moved[importNode.id] = true;
    if (family) {
        console.log('添加节点' + Date().toString());
        var mainFamily = onlyFamilies[family.mainid()];

        switch (position) {
            case 1:
                mainFamily.outAddHus(newNode);
                break;
            case 6:
                mainFamily.outAddWife(newNode);
                break;
            case 4:
                if (newNode.sex) {
                    debugger;
                    mainFamily.outAddSon(newNode);
                }
                else {
                    mainFamily.outAddDut(newNode);
                }
                break;
            default:
                console.log('无法识别的位置');
                break;
        }

        addFamliy(newNode);
        console.log('完成加入' + Date().toString());
        //处理节点信息
        //drawNode(id newNode);
        moved[newNode.id] = true;
        for (var j = 0; j < reDrawNodes.length; j++) {
            var n = reDrawNodes[j];
            var div = $("[nodeid=" + n.id + "]");
            if (div.length == 0) {
                drawNode(reDrawNodes[j]);

            }
            else {
                div.css({ "left": n.x });
            }
        }
        if (afterDbSave) {
            goMovingNode();
        }
        console.log('完成节点迁移' + Date().toString());
        console.log('time go spouse ' + Date().toString());
        getSpouseList();
        console.log('time' + Date().toString());

        AfterMoveLink();
        console.log('完成节点连线' + Date().toString());
    }
}

var goMovingNode = function () {
    setTimeout(function () {
        try {
            for (var a in moved) {
                var n = nodesById[a];
                var dd = $("[nodeid=" + n.id + "]");
                dd.css({ "left": n.x });
                console.log(n.id + "  " + n.x);
            }
        } catch (e) {
            console.log(e);
        }
        moved = {};
        links();
        AfterMoveLink();
    }, 500);
}

var afterDbSave = false;
var geneFamilies = {};
var families = {};
var onlyFamilies = {};

//需要重新画的节点
var reDrawNodes = [];

var familyNode = function () {

    //丈夫
    this.husband = "";
    //妻子列表
    this.wifes = [];
    //子女列表
    this.childrens = [];
    //儿子列表
    this.sons = [];
    //女儿列表
    this.duts = [];

    //上级家庭
    this.parentFamily = function () {
        if (this.husband) {
            var node = $nodes[this.husband.id];
            if (node && node.father) {
                return families[node.father];
            }
        }
        var node = this.wifes[0];
        node = $nodes[node.id];
        if (node && node.father) {
            return families[node.father];
        }
        return null;
    }


    //整个家庭往右移动
    this.fimalyAllMoveRight = function (x) {

        try {
            var r = this.getRightBrotherAncestors();

            if (r != null) {
                //moved = {};
                r.move(x);
                do {
                    r = r.rightFamily()
                    if (r != null) {
                        r.move(x);
                    }
                } while (r != null && r.rightFamily() != r);
            }
            else {
                //moved = {};
                var r = this.rightFamily();
                do {
                    r.move(x);
                    r = r.rightFamily();
                }
                while (r && r.rightFamily() != r);
            }
        }
        catch (e) {
            console.log(e);
        }
    }

    //获得右侧的祖先
    this.getRightBrotherAncestors = function () {
        var right = this.rightFamily();
        var self = this;
        while (right == null && self.parentFamily() != null) {
            self = self.parentFamily();
            right = self.rightFamily();
        }

        var goout = null;
        if (right) {
            while (self.parentFamily() != right.parentFamily()) {
                self = self.parentFamily();
                right = right.parentFamily();
                if (self.parentFamily() == right.parentFamily()) {
                    goout = right;
                    break;
                }
                if (self == null) {
                    break;
                }
                if (right == null) {
                    break;
                }
            }
        }
        return goout;
    }


    //获得家庭的根节点
    this.getRootNode = function () {
        if (this.husband) {
            return this.husband;
        }
        if (this.wifes.length > 0) {
            return this.wifes[0];
        }
    }

    //外部添加女儿
    this.outAddDut = function (dut) {
        dut.sex = 0;
        this.addChildren(dut);
        reDrawNodes = [];
        reDrawNodes[reDrawNodes.length] = dut;
        if (this.childrens.length > 1) {
            var p = this.childrens[this.childrens.length - 2];
            dut.y = p.y;
            dut.x = p.x + (1 + xsf) * (1 + p.spouse.length) * nwidth;
            this.fimalyAllMoveRight((1 + xsf) * nwidth);
        }
        else {
            var root = this.getRootNode();
            dut.x = root.x;
            dut.y = root.y + (1 + ysf) * nheight;
        }
    }

    //外部添加儿子
    this.outAddSon = function (son) {
        son.sex = 1;
        this.addChildren(son);
        reDrawNodes = [];
        reDrawNodes[reDrawNodes.length] = son;

        if (this.childrens.length > 1) {
            var p = this.childrens[this.childrens.length - 2];
            son.y = p.y;
            son.x = p.x + (1 + xsf) * (1 + p.spouse.length) * nwidth;
            this.fimalyAllMoveRight((1 + xsf) * nwidth);
        }
        else {
            var root = this.getRootNode();
            son.x = root.x;
            son.y = root.y + (1 + ysf) * nheight;
        }
    }

    //外部添加妻子
    this.outAddWife = function (wife) {

        wife.sex = 0;
        this.addWife(wife);
        reDrawNodes = [];
        wife.x = this.husband.x + (this.wifes.length) * (1 + xsf) * nwidth;
        reDrawNodes[reDrawNodes.length] = wife;
        if (this.childrens.length < this.wifes.length + 1) {
            this.fimalyAllMoveRight((1 + xsf) * nwidth);
        }
    }

    //外部添加丈夫
    this.outAddHus = function (hus) {

        hus.sex = 1;
        hus.x = this.wifes[0].x;
        this.wifes[0].x += (1 + xsf) * nwidth;
        this.sethusband(hus);
        reDrawNodes = [];
        reDrawNodes[reDrawNodes.length] = hus;
        reDrawNodes[reDrawNodes.length] = this.wifes[0];
        //moved[this.wifes[0].id] = true;
        if (this.childrens.length < 2) {
            this.fimalyAllMoveRight((1 + xsf) * nwidth);
        }
    }





    //添加女儿 内部使用 不调整 位置
    this.addDut = function (dut) {
        //添加女儿
        this.duts[this.duts.length] = dut;
    }
    //添加儿子 内部使用 不调整 位置
    this.addSon = function (son) {
        //添加儿子
        this.sons[this.sons.length] = son;
    }



    //添加子女
    this.addChildren = function (node) {
        this.childrens[this.childrens.length] = node;
        if (node.sex == "1") {
            this.addSon(node);
        }
        else {
            this.addDut(node);
        }
    }

    this.mainid = function () {
        if (!this.husband) {
            return this.wifes[0].id;
        }
        return this.husband.id;
    }
    this.move = function (x) {
        if (this.husband) {
            this.husband.moveXAndChildrens(x);
        }
        else {
            if (this.wifes.length > 0) {
                for (var j = 0; j < this.wifes.length; j++) {
                    this.wifes[j].moveXAndChildrens(x);
                }
            }
        }
    }
    //左边家庭
    this.leftFamily = function () {
        if (this.husband) {
            if (this.husband.left) {
                var id = this.husband.left.id;
                return families[id];
            }
        }
        else {
            var left = this.wifes[0].left;
            if (left) {
                return families[left.id];
            }
        }
        return null;
    }
    //右边家庭
    this.rightFamily = function () {
        if (this.wifes.length > 0) {
            var right = this.wifes[this.wifes.length - 1].right;
            if (right) {
                return families[right.id];
            }
        }
        else {
            if (this.husband.right) {
                return families[this.husband.right.id];
            }
        }
        return null;
    }

    //this.userid;
    this.sethusband = function (node) {
        this.husband = node;
        for (var j = 0; j < node.childrens.length; j++) {
            this.addChildren(node.childrens[j]);
        }
    }
    //添加妻子
    this.addWife = function (node) {
        for (var j = 0; j < this.wifes.length; j++) {
            if (this.wifes[j].id == node.id) {
                return;
            }
        }
        this.wifes[this.wifes.length] = node;
        for (var j = 0; j < node.childrens.length; j++) {
            this.addChildren(node.childrens[j]);
        }
    }
    this.cMinX = function () {

        var min = null;
        for (var j = 0; j < this.childrens.length; j++) {
            var id = this.childrens[j].id;
            var cf = families[id];
            if (!cf) {
                continue;
            }
            var m2 = cf.minX();
            if (min == null) {
                min = m2;
            }
            else if (m2 < min) min = m2;
        }

        return min;
    }
    this.cOnlyMax = function () {
        if (this.childrens.length > 0) {
            var c = this.childrens[this.childrens.length - 1];
            if (c.spouse.length > 0) {
                //return c.spouse[c.spouse.length - 1].x + nwidth;
            }
            if (nodeRightAppendWidth[c.id]) {
                return c.x + nodeRightAppendWidth[c.id] + nwidth;
            }
            return c.x + nwidth;
        }
        return null;
    }

    this.cOnlyMin = function () {
        if (this.childrens.length > 0) {

            var c = this.childrens[0];
            if (c.sex == "0" && c.spouse.length > 0) {
                //return c.spouse[0].x;
            }
            if (nodeLeftAppendWidth[c.id]) {
                return c.x - nodeLeftAppendWidth[c.id];
            }
            return c.x;
        }
        return null;
    }



    this.sMinX = function () {
        var min = 0;
        var n = null;
         
        if (this.husband) {
            min = this.husband.x;
            n = this.husband;
        }
        else {
            min = this.wifes[0].x;
            n = this.wifes[0];
        }
        if (n && nodeRightAppendWidth[n.id] && isShiXiTu) {
            min -= nodeRightAppendWidth[n.id];
        }
        return min;
    }
    this.sMaxX = function () {
        var max = 0;
        var n = null;
        
        if (this.wifes.length > 0 && (sxSetting.spousejoin == 0 || !isShiXiTu)) {
            max = this.wifes[this.wifes.length - 1].x + nwidth;
            n = this.wifes[this.wifes.length - 1];
        }
        else {
            max = this.husband.x + nwidth;
            n = this.husband;
        }
        if (n && isShiXiTu && nodeLeftAppendWidth[n.id]) {
            max += nodeLeftAppendWidth[n.id];
        }
        return max;
    }


    this.cMaxX = function () {
        var max = null;
        for (var j = 0; j < this.childrens.length; j++) {
            var id = this.childrens[j].id;
            var cf = families[id];
            if (!cf) {
                continue;
            }
            var m2 = cf.maxX();
            if (max == null) { max = m2; }
            else if (m2 > max) max = m2;
        }
        return max;
    }

    this.getGene = function () {
        if (this.husband) {
            return this.husband.gene;
        }
        else {
            return this.wifes[0].gene;
        }
    }
    //世代中最小的坐标
    this.geneMin = function (gene) {
        var cg = this.getGene();
        if (cg == gene) {
            return this.sMinX();
        }
        var min = null;
        if (gene > cg) {
            for (var j = 0; j < this.childrens.length; j++) {
                var id = this.childrens[j].id;
                var cf = families[id];
                if (!cf) {
                    continue;
                }
                var m2 = cf.geneMin(gene);
                if (min === null && m2 !== null) { min = m2; }
                else if (m2 !== null && m2 < min) min = m2;
            }
        }
        return min;
    }

    this.onlyGeneMax = function (gene) {
        var cg = this.getGene();
        if (cg == gene) {
            return this.sMaxX();
        }
        var max = null;
        if (gene > cg) {
            for (var j = 0; j < this.childrens.length; j++) {
                var id = this.childrens[j].id;
                var cf = families[id];
                if (!cf) {
                    continue;
                }
                var m2 = cf.geneMax(gene);
                if (max === null && m2 !== null) { max = m2; }
                else if (m2 !== null && m2 > max) max = m2;
            }
        }
        return max;
    }

    ///世代中最大的坐标
    this.geneMax = function (gene) {
        return this.onlyGeneMax(gene);
        geneLeftGo = {};
        var r = this.onlyGeneMax(gene);
        if (r != null) {
            return r;
        }
        var a = this;
        var i = 0;
        /*
        while (a.leftFamily()) {
        a = a.leftFamily();
        var p = a.onlyGeneMax(gene);
        if (p !== null) {
        return p;
        }
        if (i++ > 10) {
        break;
        }
        }
        */
        return null;
    }

    this.minX = function () {
        var min = this.sMinX();
        var cmin = this.cMinX();
        if (cmin != null) {
            if (min > cmin) min = cmin;
        }
        return min;
    }

    this.maxX = function () {
        var max = this.sMaxX();
        var cmax = this.cMaxX();
        if (cmax != null) {
            if (max < cmax) max = cmax;
        }
        return max;
    }
}

var geneLeftGo = {};

//end  校正水平位置
var movedRights = {};
var nodeMoveRight = function (node, x) {
    if (movedRights[node.id]) {
        return;
    }
    movedRights[node.id] = true;
    node.x += x;
    for (var j = 0; j < node.spouse.length; j++) {
        if (!movedRights[node.spouse[j]]) {
            node.spouse[j].x += x;
        }
    }
    for (var j = 0; j < node.childrens.length; j++) {
        nodeMoveRight(node.childrens[j], x);
    }
}

////////////////////////////////////////////一下部分不用调整  ****************、
//节点集合
var jpnodes = [];
//一次展开的数量
var oneTimeExtendCnt = 0;
//实际展开的数量
var extendNodeCnt;

var moveNodes = {};
var charnodes = {};
//根据编号进行集合
var nodesById = {};

//时代 节点 列表
var geneNodeList = {};
//整体右移
var allMove = function (x, y) {
    for (var j = 0; j < jpnodes.length; j++) {
        jpnodes[j].x += parseInt(x);
        jpnodes[j].y += parseInt(y);
    }
    jpdraw();
}

//世代排序保存
var geneIndex = {};


//家谱节点类
var jpnode = function () {
    /** TODO  扩展自己需要的内容
    如姓名 ； 头像等 。。。 
    this.name="";
    this.avatar="";
    */
    this.name = "";
    //头像
    this.avatar = "";
    //兄弟姐妹间排序
    this.sort = 0;

    //媳妇排序
    this.xfSort = 0;
    //应该修改 兄弟更换排序而影响的 X 位置偏移
    this.sortX = 0;
    //性别 0 女 1 男
    this.sex = 0;

    /************** end  */
    //存储的编号
    this.id = 0;

    //是否显示
    this.isShow = 1;
    //是否已经展开
    this.isExtend = 1;

    //删除出 对象 
    this.isDelete = 0;


    this.moveXAndChildrens = function (x) {
        if (!moved[this.id]) {
            this.x += x;
            if (nodesById[this.id] && nodesById[this.id] != this) {
                nodesById[this.id].x += x;
            }
            moved[this.id] = true;
            for (var j = 0; j < this.childrens.length; j++) {
                this.childrens[j].moveXAndChildrens(x);
            }
            for (var j = 0; j < this.spouse.length; j++) {
                this.spouse[j].moveXAndChildrens(x);
            }
        }
    }

    ///////////////////////////////////////////////////是否展开 
    this.allAfterNodes = [];

    this.brotherSort = {};

    /********************************************************************** 以下部分用于 自动纠正位置 */

    //前置节点
    this.beforeNode;

    //后缀节点集合
    this.afterNode = [];
    //位置
    this.position = 0;

    //原始位置
    this.orgPosition = 0;

    //节点深度
    this.level = 0;

    //定位容器左上角 X
    this.x = 0;
    //定位容器左上角 Y
    this.y = 0;



    //父亲节点
    this.father;
    //母亲节点
    this.mother;
    //子级节点
    this.childrens = [];
    //儿子节点
    this.son = [];
    //女儿节点
    this.daughter = [];

    //位置Char
    this.wzchar = "";
    //兄弟姐妹间排序
    this.brother = [];

    //姐妹
    this.sisters = [];

    //配偶
    this.spouse = [];


    //当前的世代
    this.gene = 0;

    //左边
    this.left;
    //右边
    this.right;

    //移动事件集合
    this.moveEvents = [];


    //移动事件
    var mEvent = function () {
        //左边节点
        this.left;
        //右边节点
        this.right;
        //移动大小 ,x大于0 往右移动, x小于0 往左移动
        this.x = 0;
        //是否使用中
        this.usering = 1;
        //触发移动的根节点集合
        this.roots = [];

    }


    //重新设置X
    this.setX = function (x) { this.x = x; }

    //重新设置Y
    this.setY = function (y) { this.y = y; }

    //设置是否显示
    this.setShow = function (isShow) {
        if (this.isShow != isShow) {
            this.isShow = isShow;
        }
        if (!this.isShow) {
            this.joinLeftRight();
        }
        if (this.isDelete) {
            this.isShow = 0;
            return;
        }


    }

    //当前节点重叠
    this.intend = function () {
        this.isExtend = 0;
        this.setShow(0);
    }
    this.extend = function () {
        this.setShow(1);
        this.isExtend = 1;


    }


    this.intendAllOut = function () {
        this.isExtend = 0;
        this.intendAll(this);
        this.setShow(1);
        this.resetAllNodes();
    }

    this.extendAllOut = function () {
        oneTimeExtendCnt = 50;
        extendNodeCnt = 0;
        this.isExtend = 1;
        this.extendAll();
        this.setShow(1);
        this.resetAllNodes();
    }
    this.intendAll = function (initial) {
        this.intend();

        for (var j = 0; j < this.allAfterNodes.length; j++) {
            var n = this.allAfterNodes[j];
            if (initial) {
                if (initial.wzchar != n.wzchar) {
                    n.intendAll();
                }
            } else {
                n.intendAll();
            }
        }
    }
    this.extendAll = function () {
        this.extend();
        if (oneTimeExtendCnt > 0) {
            if (extendNodeCnt++ >= oneTimeExtendCnt) {
                return;
            }
        }
        for (var j = 0; j < this.allAfterNodes.length; j++) {
            var n = this.allAfterNodes[j];
            if (!n.isDelete) {

                n.extendAll();
            }
        }
    }

    this.reseting = 0;
    this.clearData = function () {
        this.father = null;
        this.mother = null;
        this.childrens = [];
        this.spouse = [];
        this.left = null;
        this.right = null;
    }

    //当前节点重新画
    this.reDraw = function (afterNode) {
        console.log("重画节点");
        if (afterNode.father == this) {
            //处理子女


        }
        if (afterNode.mother == this) {

        }
        if (afterNode.spouse == this) {

        }
    }

    this.resetData = function () {

        var after = this.allAfterNodes;


        this.afterNode = [];
        for (var j = 0; j < after.length; j++) {
            after[j].clearData();
        }
        this.reseting = 1;
        for (var j = 0; j < after.length; j++) {
            var n = after[j];
            if (n.isShow && !n.isDelete) {

                switch (n.orgPosition) {
                    case 1:
                        this.addSpouse(n);
                        n.resetData();
                        break;
                    case 5:
                        if (this.sex) {
                            this.addSpouse(n);
                        }
                        else {
                            if (this.spouse.length > 0) {
                                this.spouse[0].addSpouse(n);
                            }
                            else {
                                this.addSpouse(n);
                            }
                        }
                        n.resetData();
                        break;
                }
            }
        }
        for (var j = 0; j < after.length; j++) {
            var n = after[j];
            if (n.isShow && !n.isDelete) {
                switch (n.orgPosition) {
                    case 2:
                        for (var m = 0; m < after.length; m++) {
                            if (after[m].orgPosition == 3) {
                                this.addFather(n, after[m]);
                            }
                        }
                        this.addFather(n);
                        n.resetData();
                        break;
                    case 3:
                        this.addFather(n);
                        n.resetData();
                        break;
                    case 4:
                        if (n.wzchar == this.wzchar) {
                            this.getParent().addChildern(n);
                        }
                        else {
                            if (this.spouse.length > 0) {
                                this.addChildern(n, this.spouse[0]);
                            }
                            else {
                                this.addChildern(n);
                            }
                        }
                        n.resetData();
                        break;
                }
            }
        }
        this.reseting = 0;
    }

    //全部重画
    this.resetAllNodes = function () {
        console.log('重新画树');
        var p = jpnodes[0]; //
        geneIndex = {};
        geneNodeList = {};
        p.x = 800;
        p.clearData();
        p.resetData();
    }

    //循环删除节点，包括子节点
    this.delMesting = function () {
        //往前

        this.deleteNode(1);
        //删除夫妻
        //删除父母
        //删除儿女
        for (var j = 0; j < this.afterNode.length; j++) {
            this.afterNode[j].delMesting();
        }
    }
    this.canAdd = function () {
        return judgeAuth(this.id, "add");
    }
    this.canEdit = function () {
        return judgeAuth(this.id, "edit");
    }
    this.canDelete = function () {
        return !this.hasAfter();

    }
    this.hasAfter = function () {
        if (this.allAfterNodes.length == 0) {
            return false;
        }
        var t = 0;
        var f = this.father;
        var m = this.mother;
        var spouse = this.spouse;
        if (spouse.length > 0) spouse = spouse[0];
        for (var j = 0; j < this.allAfterNodes.length; j++) {
            var p = this.allAfterNodes[j];
            if (f && p.father == f) {
                //return false;
                continue;
            }
            if (m && p.mother == m) {
                //return false;
                continue;
            }
            if (p.spouse.length > 0 && p.spouse[0] == spouse) {
                continue;
            }
            return true;
        }
        return false;
    }
    this.canExtend = function () {

        return (this.hasAfter() && this.isExtend == 0);
    }
    this.canIntend = function () {
        return this.isExtend == 1 && this.hasAfter();
    }
    this.canSort = function () {
        if (this.sex == 0) {
            if (this.spouse.lenght > 0) {
                if (this.spouse[0].spouse.length > 1) {
                    return true;
                }
            }
        }
        var p = this.getParent();
        if (p) {
            if (p.childrens.length > 1) {
                return true;
            }
        }
        return false;
        //return false;
    }
    //删除节点
    this.deleteNode = function (all) {
        if (!all) {
            if (this.afterNode.length > 0) {
                return false;
            }
        }
        var $node = $nodes[this.id];
        if ($node) {
            $node.enable = 0;
        }
        $("[nodeid=" + this.id + "]").remove();

        if (this.beforeNode) {
            this.beforeNode.allAfterNodes.removeObj(this);
            if (this.beforeNode.canDelete()) {
                drawNode(this.beforeNode);
            }
        }
        this.isDelete = 1;
        return;

        this.wzchar = "0";
        this.gene = -999999999;

        this.x = 0;
        this.y = 0;
        var b = this.beforeNode;
        //var left = this.left;
        //var right = this.right;
        this.joinLeftRight();
        var g = this.gene;
        if (geneIndex[g] == this) {
            if (this.right) {
                geneIndex[g] = this.right;
            }
            else {
                geneIndex[g] = null;
            }
        }
        b.afterNode.removeObj(this);
        var an = this.afterNode;
        for (var j = 0; j < an.length; j++) {
            var n = an[j];
            if (
             n.orgPosition == 4 || n.orgPosition == 5) {
                b.setBeforeNode(n);
                continue;
            }

            n.deleteNode(1);
        }
        this.afterNode = [];
        //this.afterNode.
        this.intend();
        this.setShow(0);
        //删除父母
        if (this == b.father) { b.father = null; }
        if (this == b.father) { b.mother = null; }
        for (var j = 0; j < this.childrens.length; j++) {
            var r = this.childrens[j];
            if (this.sex == 1) {
                if (r.father == this) {
                    r.father = null;
                }
            }
            else {
                if (r.mother == this) {
                    r.mother = null;
                }
            }
        }
        for (var j = 0; j < this.spouse.length; j++) {
            var s = this.spouse[j];
            for (var m = 0; m < s.childrens.length; m++) {
                var r = s.childrens[m];
                if (this.sex == 1) {
                    if (r.father == this) {
                        r.father = null;
                    }
                }
                else {
                    if (r.mother == this) {
                        r.mother = null;
                    }
                }
            }
        }
        if (b.spouse.contains(this)) { b.spouse.removeObj(this); }

        //删除兄弟
        return true;
    }
    //左右对接
    this.joinLeftRight = function () {
        if (!this.left) {
            geneIndex[this.gene] = null;
            if (this.right) {
                geneIndex[this.gene] = this.right;
                this.right.left = null;
            }

        }
        else {
            if (this.right) {
                this.right.left = this.left;

            }
            this.left.right = this.right;

        }

        this.left = null;
        this.right = null;


    }

    // 删除节点
    this.del = function () {

        if (this.afterNode.length > 0) {
            if (this.afterNode.length > 1) {

                jpAlter("不能删除,当前节点含关联节点,请删除关联节点");
                return false;
            }
            else if (this.afterNode[0].wzchar != this.wzchar) {
                jpAlter("不能删除,当前节点含关联节点,请删除关联节点");
                return false;
            }
        }
        var left = this.left;
        var right = this.right;
        if (this.deleteNode(1)) {

            this.resetAllNodes();
            return true;
        }
        return false;

    }


    //获得兄弟姐妹
    this.siblings = function () {
        var list = [];
        var c = this.wzchar;
        var p = this.getParent();
        if (p) {
            p.childrens.sort(keysrt("sort", 0));
            for (var j = 0; j < p.childrens.length; j++) {
                var n = p.childrens[j];
                if (n.wzchar == c) {
                    list[list.length] = n;

                }
            }
        }
        else {
            list[list.length] = this;
        }
        return list;
    }

    //兄弟中最大
    this.isSiblingsFirst = function () {
        var l = this.siblings();
        return l[0] == this;
    }

    //兄弟中最小
    this.isSiblingsLast = function () {
        var l = this.siblings();
        return l[l.length - 1] == this;
    }

    //添加节点
    this.addNode = function (node, position) {

        if (this.level == 0 && !geneIndex[0]) {

            var p = parseInt(this.gene);
            geneIndex[0] = this;
            geneNodeList[0] = [];
            geneNodeList[0][0] = this;
            if (!geneNodeList[p]) {
                geneNodeList[p] = [];
                geneNodeList[p][0] = this;
            }
            this.beforeNodes[this.wzchar] = this;
            charnodes[this.wzchar] = this;
            //nodesById[node.id] = node;
        }

        console.log("this.id: " + this.id + "  node_id: " + node.id + " node ship:" + node.position);
        console.log(this.wzchar);

        node.level = this.level + 1;
        node.orgPosition = position;

        console.log('addnode');
        var preCode = this.wzchar;
        var code = ""; // preCode + position;
        var beforeNode = this;
        var addGene = 0;
        var x = 0;
        if (!this.reseting) {
            jpnodes[jpnodes.length] = node;
        }

        switch (position) {
            case 1:
                x -= (1 + xsf) * nwidth;
                node.x = this.x + x;
                code = preCode + position;
                break;
            case 2:
                addGene--;
                x -= (1 + xsf) * 0.5 * nwidth;
                node.x = this.x + x;
                code = preCode + position;
                break;
            case 3:
                addGene--;
                x = (1 + xsf) * 0.5 * nwidth;
                node.x = this.x + x;
                code = preCode + position;
                break;
            case 4:
                //特别小心处理
                addGene++;
                node.posistion = 4;
                if (this.childrens.length > 1) {
                    for (var j = this.childrens.length - 1; j >= 0; j--) {
                        var m2 = this.childrens[j];
                        if (m2.father == this || m2.mother == this) {
                            if (m2 != node) {
                                beforeNode = m2;
                                node.level = m2.level + 1;
                                node.posistion = 7;
                                break;
                            }
                        }
                    }
                    code = beforeNode.wzchar;
                    if (code == "") { code = "4"; }
                }
                else {
                    code = preCode + position; ;
                }
                if (this.childrens.length > 0) {
                    var c = null;
                    for (var j = this.childrens.length - 1; j < this.childrens.length; j--) {
                        var c1 = this.childrens[j];
                        if (c1 != node) {
                            c = c1;
                            break;
                        }
                    }
                    if (!c) {
                        node.x = this.x + (xsf) * nwidth;
                    }
                    else if (!c.sex || c.spouse.length == 0) {
                        node.x = c.x + (1 + xsf) * nwidth;
                    }
                    else {
                        node.x = c.spouse[c.spouse.length - 1].x + (1 + xsf) * nwidth;
                    }
                }
                else {
                    node.x = this.x + (1 + xsf) * nwidth;
                }
                break;
            case 5:
                node.posistion = 5;
                if (this.sex && this.spouse.length > 1) {
                    var m = this.spouse[0];
                    for (var j = this.spouse.length - 1; j >= 0; j--) {
                        if (this.spouse[j] != node) {
                            node.level = this.spouse[j].level + 1;
                            beforeNode = this.spouse[j];
                            node.posistion = 6;
                            break;
                        }
                    }
                    code = beforeNode.wzchar;
                }
                else {
                    code = preCode + position;
                }

                if (this.spouse.length > 1) {

                    node.x = this.spouse[this.spouse.length - 2].x + (1 + xsf) * nwidth;
                }
                else {
                    node.x = this.x + (1 + xsf) * nwidth;
                }
                break;
            default:
                jpAlter('无法分析位置大小');
                break;
        }

        console.log('node id [' + node.id + ']  [x][' + node.x + ']');
        console.log(this.reseting);

        if (!this.reseting) {
            node.wzchar = code;
        }
        console.log(node.wzchar);
        node.y = this.y + (addGene * (ysf + 1) * nheight);
        beforeNode.setBeforeNode(node);
        charnodes[node.wzchar] = node;
        node.position = position;
        var g = node.gene = this.gene + addGene;
        if (!geneNodeList[g]) {
            geneNodeList[g] = [];
            geneNodeList[g][0] = node;
        }
        else {
            insertItem(geneNodeList[g], node);
        }

        var family = families[this.id];
        if (family) {
            console.log('go family back');
            return;
        }

        //计算正确的位置
        if (node.left && node.left.x > (node.x - (xsf + 1) * nwidth)) {
            console.log('左移节点');
            var left = node.left;
            var move = -(left.x - (node.x - (1 + xsf) * nwidth));
            var sm = "";
            for (var j = 1; j <= node.wzchar.length; j++) {
                var nchar = node.wzchar.substr(0, j);
                var lchar = left.wzchar.substr(0, j);
                var nn = node.beforeNodes[nchar];
                var ln = left.beforeNodes[lchar];
                if (nn && nn != ln) {
                    moveNodes = {};
                    var gen = ln;

                    if (!gen) {//TODO 逻辑不正确 
                        return;
                    }

                    gen.x += move; //记录偏移量
                    moveNodes[gen.id] = gen;
                    moveNodes[nn.id] = nn;
                    console.log('查找的根节点' + sm);
                    for (var j = 0; j < gen.afterNode.length; j++) {
                        var n = gen.afterNode[j];
                        if (!n.compare(nn) && n != nn) {
                            if (!n.moveNesting) {
                                debugger;
                            }
                            n.moveNesting(move, node.x, 0);
                        }
                    }
                    do {
                        lchar = lchar.substr(0, lchar.length - 1);
                        var p = left.beforeNodes[lchar];
                        if (p) {
                            if (!moveNodes[p.id]) {
                                p.x += move;
                                moveNodes[p.id] = p;
                            }
                            for (var j = 0; j < p.afterNode.length; j++) {
                                var n = p.afterNode[j];
                                if (!n.compare(ln) && n != nn) {
                                    n.moveNesting(move, node.x, 0);

                                }
                            }
                        }
                    } while (lchar != "");
                    break;
                }
            }
        }


        if (node.right && node.right.x < (node.x + (1 + xsf) * nwidth)) {
            console.log('右移节点');
            var right = node.right;
            var move = (node.x + (1 + xsf) * nwidth) - right.x;
            var sm = "";
            for (var j = 0; j <= node.wzchar.length; j++) {
                var nchar = node.wzchar.substr(0, j);
                var rchar = right.wzchar.substr(0, j);
                var nn = node.beforeNodes[nchar];
                var rn = right.beforeNodes[rchar];
                if (nn && nn != rn) {
                    var gen = rn;
                    moveNodes = {};
                    if (!gen || !gen.moveNesting) {
                        debugger;
                    }
                    gen.moveNesting(move, node.x, 1);
                    moveNodes[gen.id] = gen;
                    for (var j = 0; j < nn.afterNode.length; j++) {
                        var n = nn.afterNode[j];
                        if (n.compare(gen) && n != gen) {
                            n.moveNesting(move, node.x, 1);
                        }
                    }
                    do {
                        nchar = nchar.substr(0, nchar.length - 1);
                        var n = right.beforeNodes[nchar];
                        if (n) {
                            for (var j = 0; j < n.afterNode.length; j++) {
                                if (n.afterNode[j].compare(nn) && n.afterNode[j] != nn) {
                                    n.afterNode[j].moveNesting(move, node.x, 1);
                                }
                            }
                        }
                    } while (nchar != "");

                    break;
                }
            }
        }
    }

    this.beforeNodes = {};
    this.compare = function (y) {
        return compareNode(y, this);
    }
    //嵌套移动
    this.moveNesting = function (x, center, fx, bnode) {
        if (moveNodes[this.id]) {
            return;
        }
        moveNodes[this.id] = this;
        this.x += x;
        for (var j = 0; j < this.afterNode.length; j++) {
            var no = this.afterNode[j];
            no.moveNesting(x, center, fx, null);
        }

    }





    //设置排序
    this.setSortOut = function (sort) {
        if (this.sort == sort) {
            return;
        }
        //this.resetAllNodes();

        console.log('排序');
        var sort = parseInt(sort);
        var moveNodes = [];
        var c = this.wzchar;
        var parent = this.getParent();
        var old = this.sort;
        for (var j = 0; j < parent.childrens.length; j++) {

        }
        if (this.sort < sort) {
            var h = false;
            var node = this;
            do {
                h = false;
                for (var j = 0; j < node.afterNode.length; j++) {
                    if (node.afterNode[j].wzchar == c) {
                        if (node.afterNode[j].sort <= sort) {
                            moveNodes[moveNodes.length] = node.afterNode[j];
                            node = node.afterNode[j];
                            h = true;
                        }
                        break;
                    }
                }
            } while (h);
            if (moveNodes.length > 0) {
                var f = moveNodes[0];
                var l = moveNodes[moveNodes.length - 1];
                for (var j = 0; j < moveNodes.length; j++) {
                    var n = moveNodes[j];
                    n.sort -= 1;
                    for (var i = 0; i < n.spouse.length; i++) {
                        n.spouse[i].sort -= 1;
                    }
                }
                var b = this.beforeNode;
                b.afterNode.removeObj(this);
                b.allAfterNodes.removeObj(this);
                b.setBeforeNode(f);
                this.afterNode.removeObj(f);
                this.allAfterNodes.removeObj(f);

                for (var j = 0; j < l.allAfterNodes.length; j++) {
                    if (l.allAfterNodes[j].wzchar == c) {
                        var a = l.allAfterNodes[j];
                        l.afterNode.removeObj(a);
                        l.allAfterNodes.removeObj(a);
                        this.setBeforeNode(a);
                        break;
                    }
                }
                l.setBeforeNode(this);
            }
        }
        else {
            var h = true;
            var node = this;
            do {
                h = false;
                if (node.beforeNode.wzchar == c) {
                    if (node.beforeNode.sort >= sort) {
                        moveNodes[moveNodes.length] = node.beforeNode;
                        node = node.beforeNode;
                        h = true;
                    }
                }
            } while (h);
            if (moveNodes.length > 0) {
                for (var j = 0; j < moveNodes.length; j++) {
                    var n = moveNodes[j];
                    n.sort += 1;
                    for (var i = 0; i < n.spouse.length; i++) {
                        n.spouse[i].sort += 1;
                    }
                }
                var b = this.beforeNode;
                b.afterNode.removeObj(this);
                b.allAfterNodes.removeObj(this);

                var ns = [];

                for (var m = 0; m < this.allAfterNodes.length; m++) {
                    if (this.allAfterNodes[m].wzchar == c) {
                        ns[ns.length] = this.allAfterNodes[m];
                    }
                }
                var l = moveNodes[0];
                for (var j = 0; j < ns.length; j++) {
                    var m1 = ns[j];
                    this.allAfterNodes.removeObj(m1);
                    this.afterNode.removeObj(m1);
                    l.setBeforeNode(m1);

                }
                var b = moveNodes[moveNodes.length - 1].beforeNode;
                var f = moveNodes[moveNodes.length - 1];
                b.afterNode.removeObj(f);
                b.allAfterNodes.removeObj(f);
                this.setBeforeNode(f);
                //f.setBeforeNode(this);
                b.setBeforeNode(this);
            }
        }
        this.sort = sort;
        for (var j = 0; j < this.spouse.length; j++) {
            this.spouse[j].sort = sort + 0.001 * (j + 1);
        }
        this.resetAllNodes();
    }



    //座椅
    //设置前置节点
    this.setBeforeNode = function (node) {
        node.beforeNode = this;
        for (var j in this.beforeNodes) {
            node.beforeNodes[j] = this.beforeNodes[j];
        }
        node.beforeNodes[node.wzchar] = node;
        this.afterNode[this.afterNode.length] = node;
        if (!this.allAfterNodes.contains(node)) {
            this.allAfterNodes[this.allAfterNodes.length] = node;
        }
    }
    //不考虑多妻

    //不考虑嫁出去后的父母

    //添加父母节点 父母同步添加
    this.addFather = function (f, m) {
        if (this.father != null) {
            return false;
        }
        var father;
        var mother;
        //;有母亲需要 变换 母亲 添加节点
        if (this.mother && this.mother.id != m.id) {
            this.mother.addSpouse(f);
            m = this.mother;
        }
        console.log("add father");
        this.addNode(f, 2);
        this.father = f;
        f.childrens[f.childrens.length] = this;

        if (m) {
            console.log("add mother");
            this.addNode(m, 3);
            this.mother = m;
            m.childrens[m.childrens.length] = this;
            var h = false;
            for (var j = 0; j < f.spouse.lenght; j++) {
                if (f.spouse[j].id == m.id) {
                    h = true;
                }
            }
            if (!h) {
                f.spouse[f.spouse.length] = m;
            }
            var h = false;
            for (var j = 0; j < m.spouse.lenght; j++) {
                if (m.spouse[j].id == f.id) {
                    h = true;
                }
            }
            if (!h) {
                m.spouse[m.spouse.length] = f;
            }
        }
        return true;
    };

    //重画当前节点 及后备节点

    //添加配偶
    this.addSpouse = function (node) {
        if (this.sex == 0 && this.spouse.length > 0) {
            console.log("spouse error:" + node.id + "   name:" + node.name);
            //jpAlter('不好意思，暂支持一夫多妻,不支持一妻多夫'); 
            return false;
        }
        if (this.sex == 1 && this.spouse[0] == this.beforeNode && this.beforeNode) {
            console.log("spouse error:" + node.id + "  name:" + node.name);
            //jpAlter('不好意思，暂支持女婿更换配偶'); 
            return false;
        };
        if (this.sex == 1) {
            node.sex = 0;
        }
        else {
            node.sex = 1;
        }
        //node.sex = !this.sex;
        node.gene = this.gene;

        for (var j = 0; j < this.spouse.length; j++) {
            if (this.spouse[j].id == node.id) {
                return false;
            }
        }
        var scnt = this.spouse.length;


        this.spouse[this.spouse.length] = node;
        node.spouse[node.spouse.length] = this;
        if (!node.sex) {
            node.sort = this.sort + this.spouse.length * 0.001;
        }
        else {
            node.sort = this.sort - 0.5;
        }
        if (scnt == 0) {
            for (var j = 0; j < this.childrens.length; j++) {
                node.childrens[node.childrens.lenght] = this.childrens[j];
            }
        }
        if (this.sex == 1) {
            this.addNode(node, 5);
        }
        else {
            this.addNode(node, 1);
        }
        for (var j = 0; j < this.childrens.length; j++) {
            var n = this.childrens[j];
            if (this.sex == 0) {
                if (!n.father) {
                    n.father = node;
                }
            }
            else {
                if (!n.mother) {
                    n.mother = node;
                }
            }
        }
        //处理位置
        treeAddNode(this, node, node.sex == 1 ? 1 : 6);
        return true;
    };
    //获得上一个节点的 挂接点
    this.getParent = function () {
        var mother = this.mother;
        var father = this.father;
        var parent;
        if (!father) {
            parent = mother;
        }
        else {
            if (father.spouse.length > 1 && father.spouse[0].id != this.mother.id) {
                parent = mother;
            }
            if (!parent) parent = father;
        }
        return parent;
    }



    //添加子女  
    this.addChildern = function (node, other) {
        console.log('进入添加子女' + Date().toString());
        if (other == null) {
            if (this.spouse.length > 0) {
                other = this.spouse[0];
            }
        }
        if (this.sex) {
            node.father = this;
            node.mother = other;
            if (this.spouse.length > 1 && node.mother.id != this.spouse[0].id) {
                var parent = node.mother;
            }
            else {
                var parent = node.father ? node.father : node.mother;
            }
        } else {
            node.mother = this;
            if (other) {
                node.father = other;
                if (other.spouse.length > 1 && node.mother.id != other.spouse[0].id) {
                    var parent = node.mother;
                }
                else {
                    var parent = node.father ? node.father : node.mother;
                }
            }
            else {
                parent = this;
            }
        }

        parent.childrens[parent.childrens.length] = node;

        node.sort = parent.childrens.length;
        parent.addNode(node, 4);
        treeAddNode(parent, node, 4);
        return true;
    }


    //添加儿子
    this.addSon = function (node, mother) { node.sex = 1; return this.addChildern(node, mother); };


    //添加女儿
    this.addDaughter = function (node, mother) { node.sex = 0; return this.addChildern(node, mother); };

    this.addBrother = function (node) {
        var p = this.getParent();
        if (!p) {
            return false;
        }
        return p.addSon(node);
    }
    this.addSiseter = function (node) {
        var p = this.getParent();
        if (!p) {
            return false;
        }
        return p.addDaughter(node);
    }


    //获得排序排序
    this.getSort = function (f) {
        if (f == this.father || f == this.mother) {
            return this.sort;
        }
        return this.xfSort;
    }

    //设置排序
    this.setSort = function (sort, f) {
        if (!f || f == this.father || f == this.mother) {
            this.sort = sort;
        }
        this.xfSort = sort;
    }
};
//根据键排序
function keysrt(key, desc) {
    return function (a, b) {
        return desc ? ~ ~(a[key] < b[key]) : ~ ~(a[key] > b[key]);
    }
}


Array.prototype.remove = function (dx) {
    if (isNaN(dx) || dx > this.length) { return false; }
    for (var i = 0, n = 0; i < this.length; i++) {
        if (this[i] != this[dx]) {
            this[n++] = this[i]
        }
    }
    this.length -= 1
}

Array.prototype.removeObj = function (obj) {
    var s = false;
    for (var i = 0, n = 0; i < this.length; i++) {
        if (this[i] != obj) {
            this[n++] = this[i]
        }
        else {
            s = true;
        }
    }
    if (s) {
        this.length -= 1
    }
    return s;
}
Array.prototype.contains = function (item) {
    for (i = 0; i < this.length; i++) {
        if (this[i] == item) { return true; }
    }
    return false;
};

function binarySearch(items, value) {
    var startIndex = 0,
    stopIndex = items.length - 1,
    middle = Math.floor((stopIndex + startIndex) / 2);
    while (items[middle] != value && startIndex < stopIndex) {
        //adjust search area（调整查找范围） 
        if (value < items[middle]) {
            stopIndex = middle - 1;
        } else if (value > items[middle]) {
            startIndex = middle + 1;
        }
        //recalculate middle（重新计算中项索引） 
        middle = Math.floor((stopIndex + startIndex) / 2);
    }
    //make sure it's the right value（确保返回正确的值） 
    return (items[middle] != value) ? -1 : middle;
}

/** 比较节点  X 小于 Y 返回true  否则返回false  */
function compareNode(x, y) {
    var xc = x.wzchar, yc = y.wzchar;
    var xl = xc.length;
    var yl = y.wzchar.length;
    var min = xc.length < yc.length ? xc.length : yc.length;
    var startIndex = 0, stopIndex = min;
    var middle = Math.floor((startIndex + stopIndex) / 2);
    var xchar = xc.substr(0, middle), ychar = yc.substr(0, middle);
    while (startIndex < stopIndex) {
        if (xchar == ychar) {
            startIndex = middle + 1;
        }
        else {
            stopIndex = middle - 1;
        }
        middle = Math.floor((startIndex + stopIndex) / 2);
        xchar = xc.substr(0, middle), ychar = yc.substr(0, middle);
    }
    if (xchar != ychar) {
        middle--;
        xchar = xc.substr(0, middle);
    }
    var xp = x.beforeNodes[xchar];
    var yp = y.beforeNodes[xchar];
    while (xp != yp) {
        middle--;
        xchar = xc.substr(0, middle);
        xp = x.beforeNodes[xchar];
        yp = y.beforeNodes[xchar];
    }
    if (middle < min) {
        var a = xc.substr(middle, 1), b = yc.substr(middle, 1);
        if (a != b) { return a < b; }
        else {
            middle++;
            xchar = xc.substr(0, middle);
            var xp = x.beforeNodes[xchar];
            var yp = y.beforeNodes[xchar];
            return xp.sort < yp.sort;
        }
    }
    else {
        if (xl > min) {
            return xc.substr(middle, 1) < 3;
        } else {
            return yc.substr(middle, 1) > 2;
        }
    }
}

function insertItem(items, item) {
    var startIndex = 0, stopIndex = items.length - 1,
    middle = Math.floor((stopIndex + startIndex) / 2);
    var n = items[middle];
    do {
        if (compareNode(n, item)) {
            startIndex = middle + 1;
        }
        else {
            stopIndex = middle - 1;
        }
        middle = Math.floor((startIndex + stopIndex) / 2);
        if (middle < 0) middle = 0;
        n = items[middle];
    } while (startIndex < stopIndex);
    if (compareNode(n, item)) {
        middle += 1;
    }
    for (var j = items.length - 1; j >= middle; j--) {
        items[j + 1] = items[j];
    }
    items[middle] = item;
    if (middle > 0) {
        item.left = items[middle - 1];
        items[middle - 1].right = item;
    }
    if (middle < items.length - 1) {
        item.right = items[middle + 1];
        items[middle + 1].left = item;
    }
}   
 